using System.Text;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.SwaggerGen;
using UniversalAdmin.Api.Models;
using UniversalAdmin.Application.Common;
using UniversalAdmin.Application.DTOs;
using UniversalAdmin.Domain.Repositories;

namespace UniversalAdmin.Api.Controllers;

[ApiController]
[Route("api/operation-logs")]
// [Authorize("admin.system.manage")] // 临时注释掉权限验证，用于测试
public class OperationLogsController : ControllerBase
{
  private readonly IOperationLogRepository _repo;

  public OperationLogsController(IOperationLogRepository repo)
  {
    _repo = repo;
  }

  ///<summary>
  ///分页查询日志
  ///</summary>
  [HttpGet]
  public async Task<IActionResult> Search(
      [FromQuery] string? action = null,
      [FromQuery] string? resource = null,
      [FromQuery] int? resourceId = null,
      [FromQuery] int? userId = null,
      [FromQuery] DateTime? start = null,
      [FromQuery] DateTime? end = null,
      [FromQuery] int page = 1,
      [FromQuery] int size = 10)
  {
    var (items, total) = await _repo.SearchLogsAsync(
           action, resource, resourceId, userId, start, end, page, size);

    var dtos = items.Select(l => new OperationLogDto
    {
      Id = l.Id,
      UserId = l.UserId,
      Username = l.User?.Username ?? "anonymous",
      Action = l.Action,
      Resource = l.Resource,
      ResourceId = l.ResourceId,
      IpAddress = l.IpAddress,
      UserAgent = l.UserAgent,
      CreatedAt = l.CreatedAt
    });

    return Ok(ApiResponse<PagedResult<OperationLogDto>>.Success(
          new PagedResult<OperationLogDto>
          {
            Items = dtos.ToList(),
            TotalCount = total,
            PageIndex = page,
            PageSize = size
          }));
  }

  [HttpGet("search")]
  public async Task<IActionResult> Search([FromQuery] OperationLogQueryDto dto)
  {
    var (items, total) = await _repo.SearchWithUserAsync(
        dto.Username, dto.Action, dto.Resource,
        dto.StartDate, dto.EndDate,
        dto.PageIndex, dto.PageSize);

    var dtos = items.Select(l => new OperationLogDto
    {
      Id = l.Id,
      UserId = l.UserId,
      Username = l.User?.Username ?? "anonymous",
      Action = l.Action,
      Resource = l.Resource,
      ResourceId = l.ResourceId,
      IpAddress = l.IpAddress,
      UserAgent = l.UserAgent,
      CreatedAt = l.CreatedAt
    });

    return Ok(ApiResponse<PagedResult<OperationLogDto>>.Success(
        new PagedResult<OperationLogDto>
        {
          Items = dtos.ToList(),
          TotalCount = total,
          PageIndex = dto.PageIndex,
          PageSize = dto.PageSize
        }));
  }

  [HttpGet("export")]
  public async Task<IActionResult> ExportCsv(
    [FromQuery] string? action,
    [FromQuery] string? resource,
    [FromQuery] DateTime? start,
    [FromQuery] DateTime? end)
  {
    var (items, _) = await _repo.SearchLogsAsync(
        action, resource, null, null, start, end,
        pageIndex: 1, pageSize: int.MaxValue);

    var csv = new StringBuilder();
    csv.AppendLine("Id,Username,Action,Resource,ResourceId,IpAddress,CreatedAt");
    foreach (var l in items)
    {
      csv.AppendLine($"{l.Id},{l.User?.Username},{l.Action},{l.Resource},{l.ResourceId},{l.IpAddress},{l.CreatedAt:yyyy-MM-dd HH:mm:ss}");
    }

    return File(Encoding.UTF8.GetBytes(csv.ToString()),
                "text/csv",
                $"operation_logs_{DateTime.UtcNow:yyyyMMddHHmmss}.csv");
  }
}